#include "VSNormalDepthPass.h"
#include "VSSpatial.h"
#include "VSBoneNode.h"
#include "VSShaderStringFactory.h"
#include "VSConstValue.h"
#include "VSGeometry.h"
#include "VSBoneNode.h"
#include "VSResourceManager.h"
#include "VSGraphicInclude.h"
#include "VSMaterial.h"
using namespace VSEngine2;
IMPLEMENT_RTTI(VSNormalDepthPass,VSPass)
BEGIN_ADD_PROPERTY(VSNormalDepthPass,VSPass)
END_ADD_PROPERTY
IMPLEMENT_INITIAL_BEGIN(VSNormalDepthPass)
ADD_PRIORITY(VSBlendState)
ADD_PRIORITY(VSDepthStencilState)
ADD_PRIORITY(VSRasterizerState)
ADD_INITIAL_FUNCTION(InitialDefaultState)
ADD_TERMINAL_FUNCTION(TerminalDefaultState)
IMPLEMENT_INITIAL_END
bool VSNormalDepthPass::InitialDefaultState()
{

	return 1;
}
bool VSNormalDepthPass::TerminalDefaultState()
{
	return 1;
}
VSNormalDepthPass::VSNormalDepthPass()
{

	m_pMaterialInstance = NULL;
	m_pVShaderSet = NULL;
	m_pPShaderSet = NULL;
	VSBlendDesc BlendDesc;
	VSBlendState * pBlendState = VSResourceManager::CreateBlendState(BlendDesc);
	m_RenderState.SetBlendState(pBlendState);
	
}
VSNormalDepthPass::~VSNormalDepthPass()
{

	m_pMaterialInstance = NULL;

	m_pVShaderSet = NULL;
	m_pPShaderSet = NULL;
}


bool VSNormalDepthPass::Draw(VSRenderer * pRenderer)
{
	if(!pRenderer || !m_pCamera || !m_pSpatial || !m_pMaterialInstance)
		return 0;
	

	if (!GetVShader())
	{
		return 0;
	}
	if (!GetPShader())
	{
		return 0;
	}
	MaterialShaderPara1 MSPara1;
	MSPara1.pCamera = m_pCamera;
	MSPara1.pGeometry = (VSGeometry *)m_pSpatial;
	MSPara1.pMaterialInstance = m_pMaterialInstance;
	MSPara1.uiPassId = m_uiPassId;
	pRenderer->SetMaterialVShaderConstant(MSPara1,GetPassType(),m_pMaterialInstance->m_pCurVShader[GetPassType()]);
	pRenderer->SetMaterialPShaderConstant(MSPara1,GetPassType(),m_pMaterialInstance->m_pCurPShader[GetPassType()]);

	if(!pRenderer->DrawMesh((VSGeometry *)m_pSpatial,&m_RenderState,
		m_pMaterialInstance->m_pCurVShader[GetPassType()],
		m_pMaterialInstance->m_pCurPShader[GetPassType()]))
	{
		return false;
	}
	return 1;
}
bool VSNormalDepthPass::GetVShader()
{
	VSMaterial * pMaterial = m_pMaterialInstance->GetMaterial();
	if (!pMaterial)
	{
		return 0;
	}
	VSVShader * pVertexShader = NULL;

	unsigned int uiVShaderNum = 0;
	if (!m_pVShaderSet)
	{
		m_pVShaderSet = VSResourceManager::GetVertexShaderMap().GetShaderSet(VSUsedName::ms_cNormalDepthVertex);
	}
	else
	{
		uiVShaderNum = m_pVShaderSet->GetNum();
	}
	MaterialShaderPara1 MSPara1;
	MSPara1.pCamera = m_pCamera;
	MSPara1.pGeometry = (VSGeometry *)m_pSpatial;
	MSPara1.pMaterialInstance = m_pMaterialInstance;
	MSPara1.uiPassId = m_uiPassId;
	VSShaderKey::SetMaterialVShaderKey(&m_VShaderkey,MSPara1,GetPassType());
	if (m_pMaterialInstance->m_pCurVShader[GetPassType()] == NULL)
	{
		if (m_pVShaderSet)
		{
			unsigned int uiIndex = m_pVShaderSet->Find(m_VShaderkey);

			if (uiIndex != m_pVShaderSet->GetNum())
			{
				VSShader * pTemp = (*m_pVShaderSet)[uiIndex].Value;
				pVertexShader = (VSVShader *)(pTemp);
			}

		}
		if (pVertexShader == NULL)
		{
			pVertexShader = VSResourceManager::CreateVShader(MSPara1,GetPassType(),uiVShaderNum);
			if (!pVertexShader)
			{
				return 0;
			}
			if (m_pVShaderSet)
			{
				m_pVShaderSet->AddElement(m_VShaderkey,pVertexShader);
			}
		}
		m_pMaterialInstance->m_pCurVShader[GetPassType()] = pVertexShader;
	}
	else
	{
		if (m_pMaterialInstance->m_pCurVShader[GetPassType()]->m_ShaderKey == m_VShaderkey)
		{

		}
		else
		{

			if (m_pVShaderSet)
			{
				unsigned int uiIndex = m_pVShaderSet->Find(m_VShaderkey);

				if (uiIndex != m_pVShaderSet->GetNum())
				{
					VSShader * pTemp = (*m_pVShaderSet)[uiIndex].Value;
					pVertexShader = (VSVShader *)(pTemp);
				}
			}
			if (pVertexShader == NULL)
			{
				pVertexShader = VSResourceManager::CreateVShader(MSPara1,GetPassType(),uiVShaderNum);
				if (!pVertexShader)
				{
					return 0;
				}
				if (m_pVShaderSet)
				{
					m_pVShaderSet->AddElement(m_VShaderkey,pVertexShader);
				}
			}
			m_pMaterialInstance->m_pCurVShader[GetPassType()] = pVertexShader;
		}
	}

	if (!m_pVShaderSet)
	{
		VSResourceManager::GetVertexShaderMap().SetShader(VSUsedName::ms_cNormalDepthVertex,m_VShaderkey,pVertexShader);
		m_pVShaderSet = VSResourceManager::GetVertexShaderMap().GetShaderSet(VSUsedName::ms_cNormalDepthVertex);
	}
	return 1;
}
bool VSNormalDepthPass::GetPShader()
{
	VSMaterial * pMaterial = m_pMaterialInstance->GetMaterial();
	if (!pMaterial)
	{
		return 0;
	}
	unsigned int uiPShaderNum = 0;
	VSPShader * pPixelShader = NULL;
	if (!m_pPShaderSet)
	{
		m_pPShaderSet = VSResourceManager::GetNormalDepthShaderMap().GetShaderSet(pMaterial->GetResourceName());
	}
	else
	{
		uiPShaderNum = m_pPShaderSet->GetNum();
	}
	MaterialShaderPara1 MSPara1;
	MSPara1.pCamera = m_pCamera;
	MSPara1.pGeometry = (VSGeometry *)m_pSpatial;
	MSPara1.pMaterialInstance = m_pMaterialInstance;
	MSPara1.uiPassId = m_uiPassId;
	VSShaderKey::SetMaterialPShaderKey(&m_PShaderkey,MSPara1,GetPassType());

	if (m_pMaterialInstance->m_pCurPShader[GetPassType()] == NULL)
	{
		if (m_pPShaderSet)
		{
			unsigned int uiIndex = m_pPShaderSet->Find(m_PShaderkey);

			if (uiIndex != m_pPShaderSet->GetNum())
			{
				VSShader * pTemp = (*m_pPShaderSet)[uiIndex].Value;
				pPixelShader = (VSPShader *)(pTemp);
			}
		}
		if (pPixelShader == NULL)
		{
			pPixelShader = VSResourceManager::CreatePShader(MSPara1,GetPassType(),uiPShaderNum);
			if (!pPixelShader)
			{
				return 0;
			}
			if (m_pPShaderSet)
			{
				m_pPShaderSet->AddElement(m_PShaderkey,pPixelShader);
			}
		}
		m_pMaterialInstance->m_pCurPShader[GetPassType()] = pPixelShader;
	}
	else
	{
		if (m_pMaterialInstance->m_pCurPShader[GetPassType()]->m_ShaderKey == m_PShaderkey)
		{

		}
		else
		{
			if (m_pPShaderSet)
			{
				unsigned int uiIndex = m_pPShaderSet->Find(m_PShaderkey);

				if (uiIndex != m_pPShaderSet->GetNum())
				{
					VSShader * pTemp = (*m_pPShaderSet)[uiIndex].Value;
					pPixelShader = (VSPShader *)(pTemp);
				}
			}
			if (pPixelShader == NULL)
			{
				pPixelShader = VSResourceManager::CreatePShader(MSPara1,GetPassType(),uiPShaderNum);
				if (!pPixelShader)
				{
					return 0;
				}
				if (m_pPShaderSet)
				{
					m_pPShaderSet->AddElement(m_PShaderkey,pPixelShader);
				}
			}
			m_pMaterialInstance->m_pCurPShader[GetPassType()] = pPixelShader;
		}
	}

	if (!m_pPShaderSet)
	{
		VSResourceManager::GetNormalDepthShaderMap().SetShader(pMaterial->GetResourceName(),m_PShaderkey,pPixelShader);
		m_pPShaderSet = VSResourceManager::GetNormalDepthShaderMap().GetShaderSet(pMaterial->GetResourceName());
	}
	return 1;
}
